/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.tbp.persitence.dao.impl;

import br.com.tbp.exception.PersistenciaException;
import br.com.tbp.model.domain.Produto;
import br.com.tbp.model.domain.constant.TipoDeProduto;
import br.com.tbp.persitence.GerenciadorDeConexao;
import br.com.tbp.persitence.GerenciadorDeQuery;
import br.com.tbp.persitence.dao.ProdutoDao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Diego Freire
 */
public class ProdutoDaoImpl implements ProdutoDao {

    private Connection conn = null;
    private PreparedStatement pr = null;
    private ResultSet rs = null;

    public void adicionar(Produto p) throws PersistenciaException {
        if (p == null) {
            throw new PersistenciaException("Não foi informado o produto a cadastrar.");
        }

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("produto.insert"),
                    Statement.RETURN_GENERATED_KEYS);
            pr.setString(1, p.getNome());
            pr.setString(2, p.getObservacoes());
            pr.setString(3, p.getTipo().name());

            pr.executeUpdate();

            rs = pr.getGeneratedKeys();
            rs.next();
            long id = rs.getLong(1);
            p.setId(id);

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível cadastrar o produto.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr);
        }
    }

    public void atualizar(Produto p) throws PersistenciaException {
        if (p == null) {
            throw new PersistenciaException("Não foi informado o produto a atualizar.");
        }

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("produto.update"),
                    Statement.RETURN_GENERATED_KEYS);
            pr.setString(1, p.getNome());
            pr.setString(2, p.getObservacoes());
            pr.setBoolean(3, p.isAtivo());
            pr.setString(4, p.getTipo().name());
            pr.setLong(5, p.getId());

            pr.executeUpdate();

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível atualizar o produto.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr);
        }
    }

    public List<Produto> pesquisar() throws PersistenciaException {
        List<Produto> lista = new ArrayList<Produto>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("produto.select"));
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    Produto p = this.criarProduto(rs);
                    lista.add(p);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar os produtos.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return lista;
    }

    private Produto criarProduto(ResultSet rs) throws PersistenciaException {
        Produto p = null;
        try {
            p = new Produto();
            p.setId(rs.getLong("id_produto"));
            p.setNome(rs.getString("nome"));
            p.setObservacoes(rs.getString("observacoes"));
            p.setAtivo(rs.getBoolean("ativo"));
            p.setTipo(TipoDeProduto.valueOf(rs.getString("tipo")));
        } catch (SQLException sqlex) {
            StringBuilder msg = new StringBuilder("Não foi possível obter os dados do produto.");
            msg.append("\nMotivo: ").append(sqlex.getMessage());
            throw new PersistenciaException(msg.toString());
        }
        return p;
    }

    public List<Produto> pesquisar(String nome) throws PersistenciaException {
        List<Produto> lista = new ArrayList<Produto>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("produto.select.nome"));
            pr.setString(1, "%" + nome + "%");
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    Produto p = this.criarProduto(rs);
                    lista.add(p);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar os produtos.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return lista;
    }

    public Produto pesquisar(long id) throws PersistenciaException {
        Produto p = null;
        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("produto.select.id"));
            pr.setLong(1, id);
            rs = pr.executeQuery();

            if (rs != null) {
                if (rs.first()) {
                    p = this.criarProduto(rs);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar os produtos.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return p;
    }

    public List<Produto> pesquisar(int limit1, int limit2) throws PersistenciaException {
        List<Produto> lista = new ArrayList<Produto>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("produto.select.limit"));
            pr.setInt(1, limit1);
            pr.setInt(2, limit2);
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    Produto p = this.criarProduto(rs);
                    lista.add(p);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar os produtos.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return lista;
    }
}
